﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

void printString(const char* str)
{
	printf("4.打印传入的字符串：%s\n", str);//3.指针的输入特性！
	printf("5.首地址向右偏移两个字节，打印此时的字符串：%s\n", str + 2);//指针的输入特性！
}
void printStringArray(char** arr, int len)
{
	//9.arr[0]是char*类型，字符串常量；arr[0]=*(arr+0);
	for (int i = 0; i < len; i++)
	{
		printf("10.输出char*类型指针数组的元素：%s\n", arr[i]);//aaaaa,...,eeeee
	}
}
void printDoubleArray(double* arr, int len) {}

//11.指针的输出特性，被调函数分配内存，主调函数使用内存；
void allocateSpacePointerOutput(char** temp)
{
	char* p = malloc(100);
	memset(p, 0, 100);
	strcpy(p, "hello world!");

	//12.指针的间接赋值；
	*temp = p;
}

//1.主调函数分配内存，被调函数使用内存，指针的输入特性；
void testPointerInput()
{
	//2.堆上分配内存；
	char* s = malloc(sizeof(char) * 100);
	memset(s, 0, 100);
	strcpy(s, "3.指针的输入特性！");
	printString(s);

	//6.栈上分配内存；指针数组strs，存储指针变量的数组，而元素“aaaaa”实际上是存储在常量池；
	char* strs[] = { "aaaaa","bbbbb" ,"ccccc" ,"ddddd" ,"eeeee" };
	//7.求出strs的长度；
	int len = sizeof(strs) / sizeof(strs[0]);

	printStringArray(strs, len);

	//8.数组名arr作为函数的参数时，会退化为指向数组首元素的指针；即*arr=arr[0];
	double arr[] = { 1.1,2.2,3.3,4.4,5.5 };

	char* p = NULL;
	allocateSpacePointerOutput(&p);
	printf("13.使用二级指针来修改一级指针的值，间接赋值，则p指向的值为：%s\n", p);//hello world!
	if (p != NULL)
	{
		free(p);
		p = NULL;
	}
}

//main190：指针的输入输出特性
int main190()
{
	testPointerInput();

	char* p = "hello world";
	printf("15.输出p的地址：%d\n", &p);//14219148
	char** pp = &p;
	*pp = "你好！";
	printf("14.输出p指向的值：%s\n", p);//你好！
	//17.**p的地址指向*p，*p的地址指向p，p的地址指向字符串；**pp=&p; *pp=p="你好"; **pp=*p=p=&p;
		//p的地址始终没变，变的是p地址指向的值；
	printf("16.二级指针pp获取到一级指针p的地址，则p的地址：%d\n", &p);//14219148

	int* pInt = 10;
	int** ppInt = &pInt;
	*ppInt = 100;
	printf("18.和上面一样，通过二级指针ppInt指向的值，改变pInt指向的值，即pInt：%d\n", pInt);//100

	char str[] = "Pointer String";
	char* pStr = str;
	*pStr = 'H';
	//20.此时*pStr=str[0]，使用指针可以修改栈区和堆区的字符串，但是不能修改常量区字符串；但是能通过修改指向
		//字符串常量的地址，来达到修改目的；
	printf("19.使用指针修改字符数组str，则str为：%s\n", str);//Hointer String

	system("pause");
	return EXIT_SUCCESS;
}